package com.chezai.client.presenter;

import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;

import com.baidu.aip.face.FaceCropper;
import com.baidu.aip.face.FaceDetectManager;
import com.baidu.aip.face.FileImageSource;
import com.baidu.aip.face.ImageFrame;
import com.baidu.idl.facesdk.FaceInfo;
import com.chezai.client.face.APIService;
import com.chezai.client.face.exception.FaceError;
import com.chezai.client.face.model.AccessToken;
import com.chezai.client.face.model.FaceModel;
import com.chezai.client.face.utils.ImageSaveUtil;
import com.chezai.client.face.utils.ImageUtil;
import com.chezai.client.face.utils.OnResultListener;
import com.chezai.client.global.Config;
import com.chezai.client.global.TerminalApplication;
import com.chezai.client.inter.ICamera2View;
import com.chezai.client.utils.DialogUtils;
import com.orhanobut.logger.Logger;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * Camera2Presenter
 * Created by likunyang on 2018/1/25.
 */

public class Camera2Presenter extends BasePresenter<ICamera2View> {
    public static int VERIFY_ERROR_LOW = 0x0003;
    public static int VERIFY_ERROR_DEFAULT = 0x0002;

    public boolean isUploading;
    private FaceDetectManager detectManager;
    private OnDetectFaceListener mDetectListener;

    public Camera2Presenter() {
        detectManager = new FaceDetectManager(TerminalApplication.mContext);
    }

    public void upload(Bitmap face, String uid) {
        if (isUploading) {
            return;
        }
       DialogUtils.showProgressBarDialog(mContext, "人脸认证中...");
        isUploading = true;
        try {
            final File file = File.createTempFile(UUID.randomUUID().toString() + "", ".jpg");
            ImageUtil.resize(face, file, 400, 400);
            ImageSaveUtil.saveCameraBitmap(mContext, face, "head_tmp.jpg");
            APIService.getInstance().verify(new OnResultListener<FaceModel>() {
                @Override
                public void onResult(FaceModel result) {
                   DialogUtils.dismissDialog();
                    isUploading = false;
                    deleteFace(file);
                    if (result == null) {
                        if (isViewAttached()) mvpView.verifyFailed(VERIFY_ERROR_DEFAULT);
                        showToast("人脸校验不通过,请确认是否已注册", Toast.LENGTH_SHORT);
                        finish();
                        return;
                    }
                    Logger.t(TAG).i(result.getScore() + " " + result.getFaceliveness() + " " + result.getUid());
                    if (result.getScore() >= 65) {
                        if (isViewAttached()) mvpView.verifySucess();
                        return;
                    } else if (result.getScore() < 65 && result.getScore() >= 50) {
                        showToast("拍照结果识别率低，请重新拍照", Toast.LENGTH_SHORT);
                        if (isViewAttached()) mvpView.verifyFailed(VERIFY_ERROR_LOW);
                    } else if (result.getScore() < 50) {
                        if (isViewAttached()) mvpView.verifyFailed(VERIFY_ERROR_DEFAULT);
                        showToast("人脸校验不通过", Toast.LENGTH_SHORT);
                        finish();
                        return;
                    }
                }

                @Override
                public void onError(FaceError error) {
                    error.printStackTrace();
                   DialogUtils.dismissDialog();
                    isUploading = false;
                    deleteFace(file);
                    int code = error.getErrorCode();
                    if (code == 216300 || code == 216500 || code == 216615 || code == 216402) {
                        String msg = "";
                        switch (code) {
                            case 216300:
                                msg = "数据库异常,请重试";
                                break;
                            case 216500:
                                msg = "未知错误,请重试";
                                break;
                            case 216615:
                                msg = "服务处理该图片失败,请重试";
                                break;
                            case 216402:
                                msg = "未找到人脸,请重试";
                                break;
                        }
                        showToast(msg, Toast.LENGTH_LONG);
                        if (isViewAttached()) mvpView.verifyFailed(VERIFY_ERROR_LOW);
                        return;
                    } else if (code == 216611) {
                        showToast("人脸校验不通过,请确认是否已注册", Toast.LENGTH_LONG);
                    } else if (code == 10000) {
                        showToast("人脸校验不通过,请检查网络后重试", Toast.LENGTH_SHORT);
                    } else if (code == 110) {
                        showToast("Token失效", Toast.LENGTH_SHORT);
                        getToken();
                    } else {
                        showToast("人脸校验不通过:" + code, Toast.LENGTH_SHORT);
                    }
                    if (isViewAttached()) mvpView.verifyFailed(VERIFY_ERROR_DEFAULT);
                }
            }, file, uid);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }
    }

    private void showToast(final String msg, final int dur) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(mContext, msg, dur).show();
            }
        });
    }

    /**
     * 初始化百度人脸比对Api Token
     */
    private void getToken() {
        // 用ak，sk获取token, 调用在线api，如：注册、识别等。为了ak、sk安全，建议放您的服务器，
        APIService.getInstance().initAccessTokenWithAkSk(new OnResultListener<AccessToken>() {
            @Override
            public void onResult(AccessToken result) {
                APIService.getInstance().setAccessToken(result.getAccessToken());
                if (isViewAttached()) mvpView.getAccessToken();
            }

            @Override
            public void onError(FaceError error) {
                error.printStackTrace();
                showToast("人脸校验不通过", Toast.LENGTH_SHORT);
                if (isViewAttached()) mvpView.verifyFailed(VERIFY_ERROR_DEFAULT);
            }
        }, mContext, Config.apiKey, Config.secretKey);
    }

    private void deleteFace(File file) {
        if (file != null && file.exists()) {
            file.delete();
        }
    }

    private void finish() {
        if (isViewAttached()) {
            mvpView.finishView();
        }
    }

    public void deletePhoto(String photoPath) {
        File file = new File(photoPath);
        deleteFace(file);
    }

    public String detect(final String filePath) {
        FileImageSource fileImageSource = new FileImageSource();
        fileImageSource.setFilePath(filePath);
        detectManager.setImageSource(fileImageSource);
        detectManager.setOnFaceDetectListener(new FaceDetectManager.OnFaceDetectListener() {
            @Override
            public void onDetectFace(int status, FaceInfo[] faces, ImageFrame frame) {
                if (faces != null) {
                    Bitmap cropBitmap = FaceCropper.getFace(frame.getArgb(), faces[0], frame.getWidth());
                    if (mDetectListener != null) {
                        mDetectListener.detectFace(cropBitmap);
                    }
                } else {
                    if (mDetectListener != null) {
                        mDetectListener.detectFaceError();
                    }
                }
            }
        });
        detectManager.start();
        return "";
    }

    public void setOnDetectFaceListener(OnDetectFaceListener listener) {
        this.mDetectListener = listener;
    }

    public interface OnDetectFaceListener {
        void detectFace(Bitmap bitmap);

        void detectFaceError();
    }

}
